/** 
 * main.h
 * hzheng, 2023.08.24
 */

#ifndef MAIN_H
#define MAIN_H


/**
 * hi3861 registers definition
 */
 
#define GPIO_ODR *((volatile unsigned int *)0x50006000)

#define UART0_DR *((volatile unsigned int *)0x40008000)
#define UART0_FR *((volatile unsigned int *)0x40008018)
#define UART0_IBRD *((volatile unsigned int *)0x40008024)
#define UART0_FBRD *((volatile unsigned int *)0x40008028)
#define UART0_LCR_H *((volatile unsigned int *)0x4000802c)
#define UART0_CR *((volatile unsigned int *)0x40008030)

#define WATCHDOG_CRR *((volatile unsigned int *)0x4000000c)

#define TIMER0_CONTROLREG *((volatile unsigned int *)0x40050008)
#define TIMER0_LOADCOUNT *((volatile unsigned int *)0x40050000)
#define TIMER0_EOI *((volatile unsigned int *)0x4005000c)

#define TIMER2_CONTROLREG *((volatile unsigned int *)0x40050030)
#define TIMER2_LOADCOUNT *((volatile unsigned int *)0x40050028)
#define TIMER2_EOI *((volatile unsigned int *)0x40050034)

#define TIMER3_CONTROLREG *((volatile unsigned int *)0x40050044)
#define TIMER3_LOADCOUNT *((volatile unsigned int *)0x4005003c)
#define TIMER3_EOI *((volatile unsigned int *)0x40050048)

#define TIMEOUT_PERIOD 40000000-1   //about 1s

#define TIMERS_RAWINTSTATUS *((volatile unsigned int *)0x400500a8)
#define TIMERS_INTSTATUS *((volatile unsigned int *)0x400500a0)
#define TIMERS_EOI *((volatile unsigned int *)0x400500a4)

#define CLDO_CTL_CLKEN_REG  *((volatile unsigned int *)0x40010030) 

/**
 * define task context structure and initial value
 */

typedef struct {
    unsigned int sp;
    unsigned int tp;
    unsigned int t6;
    unsigned int t5;
    unsigned int t4;
    unsigned int t3;
    unsigned int t2;
    unsigned int t1;
    unsigned int t0;
    unsigned int s11;
    unsigned int s10;
    unsigned int s9;
    unsigned int s8;
    unsigned int s7;
    unsigned int s6;
    unsigned int s5;
    unsigned int mstatus;
    unsigned int mepc;
    unsigned int a7;
    unsigned int a6;
    unsigned int a5;
    unsigned int a4;
    unsigned int a3;
    unsigned int a2;
    unsigned int a1;
    unsigned int a0;
    unsigned int s4;
    unsigned int s3;
    unsigned int s2;
    unsigned int s1;
    unsigned int s0;
    unsigned int ra;
} TaskContext;

#define EMPTY_STACK                 0xCACA

#define TP_INIT_VALUE  0x02020202L
#define SP_INIT_VALUE  0x03030303L
#define S11_INIT_VALUE 0x04040404L
#define S10_INIT_VALUE 0x05050505L
#define S9_INIT_VALUE  0x06060606L
#define S8_INIT_VALUE  0x07070707L
#define S7_INIT_VALUE  0x08080808L
#define S6_INIT_VALUE  0x09090909L
#define S5_INIT_VALUE  0x10101010L
#define S4_INIT_VALUE  0x11111111L
#define S3_INIT_VALUE  0x12121212L
#define S2_INIT_VALUE  0x13131313L
#define S1_INIT_VALUE  0x14141414L
#define FP_INIT_VALUE  0x15151515L
#define T6_INIT_VALUE  0x16161616L
#define T5_INIT_VALUE  0x17171717L
#define T4_INIT_VALUE  0x18181818L
#define T3_INIT_VALUE  0x19191919L
#define A7_INIT_VALUE  0x20202020L
#define A6_INIT_VALUE  0x21212121L
#define A5_INIT_VALUE  0x22222222L
#define A4_INIT_VALUE  0x23232323L
#define A3_INIT_VALUE  0x24242424L
#define A2_INIT_VALUE  0x25252525L
#define A1_INIT_VALUE  0x26262626L
#define T2_INIT_VALUE  0x28282828L
#define T1_INIT_VALUE  0x29292929L
#define T0_INIT_VALUE  0x30303030L

#define OS_TASK_MAGIC_WORD 0xCCCCCCCC
#define OS_TASK_STACK_INIT 0xCACACACA


/**
 * define task control block structure
 */

typedef struct {
  unsigned int sp;
  unsigned int mepc;
} TaskCtrlBlock;

typedef struct {
  TaskCtrlBlock *currentTask;
  TaskCtrlBlock *nextTask;
} TaskCtrl;

TaskCtrl gTaskCtrl;

#endif
